/*
 * Copyright 2012 Quytelda Gaiwin
 *
 *	Licensed under the Apache License, Version 2.0 (the "License");
 *	you may not use this file except in compliance with the License.
 *	You may obtain a copy of the License at
 *
 *		http://www.apache.org/licenses/LICENSE-2.0
 *
 *	Unless required by applicable law or agreed to in writing, software
 *	distributed under the License is distributed on an "AS IS" BASIS,
 *	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *	See the License for the specific language governing permissions and
 *	limitations under the License.
 */

package org.tamalin.panthersleek;

import java.io.*;
import java.security.*;
import java.util.ArrayList;
import javax.swing.JOptionPane;
import javax.crypto.*;
import javax.crypto.spec.*;
import javax.security.auth.DestroyFailedException;
import java.security.cert.CertificateException;
import java.util.logging.*;
import java.util.Enumeration;

/**
 * @author Quytelda K. Gaiwin
 */
public class KeyImporterExporter implements Runnable
{
	public KeyImporterExporter(File importFile)
	{
		export = false;
		file = importFile;
	}
	
	public KeyImporterExporter(File exportFile, PantherKey k)
	{
		export = true;
		file = exportFile;
		key = k;
	}
	
	public void run()
	{	
		// Get a password for the exported key.
		PasswordPrompt pp = new PasswordPrompt(null, true, "Please enter key password:");
		pp.setVisible(true);
		char[] password = pp.getPassword();
		
		// If the password is null, the dialog is canceled.
		if(password == null) return;
		
		try
		{
			ks = KeyStore.getInstance("JCEKS");
			
			if(export) //Exporting an existing key to file.
			{
				Logger.getLogger(KeyImporterExporter.class.getName()).log(Level.FINE, "Exporting key {0}", key.getDisplayName());
				
				// initialize the keystore object
				ks.load(null, password);

				// Create a password protected entry in the keystore
				// use the key's display name as an alias
				SecretKey secretKey = (SecretKey) key.getKey();
				KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(secretKey);
				KeyStore.PasswordProtection passProtection = new KeyStore.PasswordProtection(password);
				ks.setEntry(key.getDisplayName(), entry, passProtection);

				// Destroy the PasswordProtection object to remove the password from memory.
				passProtection.destroy();
				
				//Write out the contents of the keystore to the disk file.
				FileOutputStream fos = new FileOutputStream(file);
				ks.store(fos, password);
				
				// Destroy the password by overwriting it with 0s
				for(int i = 0; i < password.length; i++) password[i] = 0;
			}
			else //Importing a key from file into memory.
			{
				// Create a new FileInputStream pointing to the keystore file, and load the keystore's contents
				FileInputStream fis = new FileInputStream(file);
				ks.load(fis, password);
				
				// For every key in the keystore, create a PantherKey object, and load it into the program
				// The key alias will serve as it's display name
				Enumeration<String> aliases = ks.aliases();
				while(aliases.hasMoreElements())
				{
					String alias = aliases.nextElement();
					PantherKey pk = new PantherKey(ks.getKey(alias, password), Panther.getNumberOfKeys(), alias);
					loadKey(pk);
				}
			}
		}
		catch(Exception ex)
		{
			Logger.getLogger(KeyImporterExporter.class.getName()).log(Level.SEVERE, null, ex);
		}
	}

	private void loadKey(PantherKey pk)
	{
		for (KeyDepositor depositor : depositors)
		{
			depositor.loadKey(pk);
		}
	}

	public void installKeyDepositor(KeyDepositor depositor)
	{
		if(depositors == null) depositors = new ArrayList<KeyDepositor>();
		depositors.add(depositor);
	}

	private File file;
	private PantherKey key;
	private ArrayList<KeyDepositor> depositors;
	private boolean export = false;
	KeyStore ks = null;
}
